#============================================================
#	Item Manager
#============================================================
#  物品管理
# * 调用 add_item 方法传入 Dictionary 类型的数据进行添加物品数据
# * 调用 remove 开头的方法移除物品
# * 调用 take_out 方法取出物品
# * 调用 load_data 方法加载数据
# * 调用 save_data 方法保存数据
#============================================================
# @datetime: 2022-2-18 21:45:00
#============================================================
class_name ItemManager extends Node


##  物品被新添加时
signal item_added(item, item_id)
##  物品发生改变时
signal item_changed(item, item_id)
##  物品被移除时
signal item_removed(item, item_id)


## 物品数据对象
var __item_data__ := __ItemData__.new().init_config(
	# name 键的值作为主键（作为记录唯一的对象）（添加的数据要包含有 name 这个 key）
	"name",
	# 对添加数据进行操作的对象，这个非常重要
	# （按 Ctrl 并点击这个类进行查看操作内容，查看 __ItemData__ 类的 _init 查看介绍）
	__Data_Handle__

# 要分组的 key 列表，这里我我传入了一个“type”，让其对添加的数据
# 的这个 key 的值进行分组，也就是对物品的 type 的值进行分组
).add_group_key(["type"]) as __ItemData__


# [ 回调处理数据 ] 
class __Data_Handle__:
	# 两个数据比较时会清除这个 key
	# 如果除了这几个 key 之外的值都一样
	# 则调用 add_data 对数据进行追加
	# 否则调用 new_data 添加为新的数据
	static func get_earse_key() -> Array:
		return ['name', 'count', 'id']
	
	# 添加的数据时，对新添加的数据的操作
	static func new_data(data: Dictionary, id: String) -> void:
		if not data.has("count"):
			data['count'] = 1
		data['id'] = id
	
	# 对追加的数据的操作
	static func add_data(a: Dictionary, b: Dictionary) -> void:
		a['count'] += b['count'] if b.has('count') else 1


#============================================================
#   Set/Get
#============================================================
##  获取所有物品
## @return  
func get_all_item_list() -> Array:
	return __item_data__.get_data().values()

##  获取所有物品数据
func get_all_item_data() -> Dictionary:
	return __item_data__.get_data()

##  根据物品 Id名称 获取数据
## @id  物品的 ID名称
## @return  返回对应物品数据，如果没有，则返回空字典
func get_item_by_id(id: String) -> Dictionary:
	if __item_data__.has_id_key(id):
		return __item_data__.get_data_by_id_key(id)
	else:
		return {}

## 根据物品名称获取物品数据
func get_item_by_item_name(item_name: String) -> Array:
	return __item_data__.get_data_by_key_value(item_name)

##  获取对应类型的物品
## @type  物品类型
func get_item_by_type(type: String) -> Array:
	return __item_data__.get_data_list_by_group_value("type", type)



#============================================================
#   内置
#============================================================
func _init():
	__item_data__.connect("data_new_added", self, "_data_new_added")
	__item_data__.connect("data_changed", self, "_data_changed")
	__item_data__.connect("data_removed", self, "_data_removed")


#============================================================
#   连接信号
#============================================================
func _data_new_added(data, item_id):
	emit_signal('item_added', data, item_id)

func _data_changed(data, item_id):
	emit_signal('item_changed', data, item_id)

func _data_removed(data, item_id):
	emit_signal("item_removed", data, item_id)


#============================================================
#   自定义
#============================================================
## 初始化 item_data
func __init_item_data__():
	if not __item_data__.is_connected("data_new_added", self, "_data_new_added"):
		__item_data__.connect("data_new_added", self, "_data_new_added")
		__item_data__.connect("data_changed", self, "_data_changed")
		__item_data__.connect("data_removed", self, "_data_removed")


##  加载数据
## （get_data_resource() 获取保存的资源 ）
func load_data(path: String) -> void:
	var temp = load(path) as __ItemData__
	if temp:
		__item_data__ = temp
		__init_item_data__()
		print("[ 加载成功 ] ", path)
		# 发出信号
		var data = __item_data__.get_data()
		for id_key in data:
			__item_data__.emit_signal("data_new_added", data[id_key], id_key)
	else:
		printerr("[ 加载失败 ] ", path)


##  保存数据
func save_data(path: String) -> void:
	# 后缀名需要是 tres 
	if not path.get_extension() in ['tres', 'res']:
		path += ".tres"
	# 保存
	var result = ResourceSaver.save(path, __item_data__)
	if result == OK:
		print("[ 保存成功 ]：", path)
	else:
		printerr('[ 保存失败 ]：', result)

##  添加物品 
## @item  物品数据
## @custom_attribute  对物品修改的属性
## @return  返回物品的 ID名称
func add_item(item: Dictionary, custom_attribute: Dictionary = {}) -> String:
	if not custom_attribute.empty():
		for key in custom_attribute:
			item[key] = custom_attribute[key]
	return __item_data__.add_data(item)


##  添加多个物品
## @return  返回添加的物品的 ID 列表
func add_items(item_list: Array) -> Array:
	var id_list := []
	var id 
	for item in item_list:
		id = add_item(item)
		if not id_list.has(id):
			id_list.push_back(id)
	return id_list


##  移除所有这个名字的物品
## @item_name  物品名
## @return  移除掉的物品的 ID名称
func remove_by_item_name(item_name: String) -> void:
	__item_data__.remove_by_value_key(item_name)


##  根据 Id名称 移除物品 
## @id  物品 id 名称
func remove_by_id(id: String) -> void:
	__item_data__.remove_by_id_key(id)

##  删除多个物品
## @id_list  物品的 ID 列表
func remove_items_by_id(id_list: Array) -> void:
	for id in id_list:
		remove_by_id(id)

##  取出物品
## @id  物品的 Id名称
## @count  取出数量
## @return  返回取出的物品
func take_out(id: String, count: int = 1) -> Dictionary:
	# 获取这个物品的数据
	var item = get_item_by_id(id)
	if not item.empty():
		# 判断数量是否超过
		var temp_item = item.duplicate(true)
		if temp_item['count'] > count:
			item['count'] -= count
			temp_item['count'] = count
			_data_changed(item, id)
		else:
			temp_item['count'] = item['count']
			__item_data__.remove_by_id_key(id)	# 全部取出了所以移除
		# 返回数据
		return temp_item
	else:
		return {}


##  获取物品的数量
func get_item_count(id: String) -> int:
	return __item_data__.get_data_by_id_key(id)['count']


